﻿using System;
using System.ComponentModel;
using Microsoft.Xna.Framework;

namespace Narwhunderful.Aphelia.Framework.UI
{

    [EditorBrowsable(EditorBrowsableState.Never)]
    public abstract class UIInternalComponent : UIBaseComponent, IUIInternalComponent
    {

        public event EventHandler<EventArgs> GotFocus = null;
        public event EventHandler<EventArgs> LostFocus = null;

        IUIContainerComponent _parent = null;
        public virtual IUIContainerComponent Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                _parent = value;
            }
        }

        public override bool NeedsUpdate
        {
            get
            {
                return base.NeedsUpdate;
            }
            set
            {
                base.NeedsUpdate = value;
                if (_parent != null && value) _parent.NeedsUpdate = true;
            }
        }

        string _name;
        public virtual string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (_name != null)
                {
                    if (!base.UIManager.HUD.ComponentNames.ContainsKey(_name)) base.UIManager.HUD.ComponentNames.Remove(_name);
                }
                base.UIManager.HUD.ComponentNames.Add(value, this);
                _name = value;
            }
        }

        bool _canFocus = true;
        public bool CanFocus
        {
            get
            {
                return _canFocus;
            }
            set
            {
                _canFocus = value;
            }
        }

        bool _isFocused = false;
        public bool IsFocused
        {
            get
            {
                return _isFocused;
            }
        }

        public UIInternalComponent(UIManager manager)
            : base(manager)
        {
        }

        protected override void UpdateRenderLocation()
        {
            base.UpdateRenderLocation();
            if (_parent != null) base.RenderLocation = new Vector2(_parent.ActualLocation.X + base.RenderLocation.X, _parent.ActualLocation.Y + base.RenderLocation.Y);
        }

        protected override void UpdateActualLocation()
        {
            base.UpdateActualLocation();
            if (_parent != null) base.ActualLocation = new Vector2(_parent.ActualLocation.X + base.Location.X, _parent.ActualLocation.Y + base.Location.Y);
        }

        protected override void UpdateWorldTransform()
        {
            base.UpdateWorldTransform();
            if (_parent != null) base.WorldTransform *= Matrix.CreateTranslation(new Vector3(_parent.ActualLocation, 0.0f));
        }

        protected override void UpdateScissor()
        {
            base.UpdateScissor();
            if (_parent != null) base.ScissorRectangle = Graphics.DrawingContext2D.RectangleIntersect(base.ScissorRectangle, _parent.ScissorRectangle);
        }

        public override void Draw()
        {
            this.Draw(false);
        }

        public virtual void Draw(bool drawFocusedComponent)
        {
            if (CanDraw(drawFocusedComponent))
            {
                BeginDraw();
                if (CanDrawBackground()) InternalDrawBackground();
                InternalDraw();
                if (CanDrawOverlay()) InternalDrawOverlay();
                EndDraw();
            }
        }

        public override bool CanDraw()
        {
            return this.CanDraw(false);
        }

        public virtual bool CanDraw(bool drawFocusedComponent)
        {
            if (!drawFocusedComponent && _isFocused) return false;
            return base.CanDraw();
        }

        public virtual void Focus()
        {
            if (_isFocused) return;
            if (!_canFocus) return;
            _isFocused = true;
            this.OnGotFocus(this, new EventArgs());
        }

        public virtual void LoseFocus()
        {
            _isFocused = false;
            OnLostFocus(this, new EventArgs());
        }

        public override void Show()
        {
            base.Show();
            this.Focus();
        }

        protected internal override void OnKeyDown(object sender, Input.Keyboard.KeyEventArgs e)
        {
            if (_isFocused) base.OnKeyDown(sender, e);
        }

        protected internal override void OnKeyPress(object sender, Input.Keyboard.KeyEventArgs e)
        {
            if (_isFocused) base.OnKeyPress(sender, e);
        }

        protected internal override void OnKeyUp(object sender, Input.Keyboard.KeyEventArgs e)
        {
            if (_isFocused) base.OnKeyUp(sender, e);
        }

        protected internal virtual void OnGotFocus(object sender, EventArgs e)
        {
            if (GotFocus != null) GotFocus(sender, e);
        }

        protected internal virtual void OnLostFocus(object sender, EventArgs e)
        {
            if (LostFocus != null) LostFocus(sender, e);
        }

    }

}
